//
//		XR16L78X UART DRIVER 
//
//      (c) 2008 mocom software GmbH & Co KG 
//		for European Microsoft Innovation Center
//
//      $Author: volker $
//      $Date: 2009-10-01 18:51:54 +0200 (Do, 01. Okt 2009) $
//      $Revision: 509 $
//
//		See HAG_usart_funtions on how to use this along with
//		on-chip uarts.
//
#include <tinyhal.h>
#include "XR16L78X_USART.h"
#include "..\usart_options.h"

//--//

#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section zidata = "g_XR16L78X_USART_Driver"
#endif

XR16L78X_USART_Driver g_XR16L78X_USART_Driver;

#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section zidata
#endif

static inline unsigned long CalcBaudrate(unsigned long baudrate, unsigned long sample, unsigned long prescale)
{
	unsigned long inclk;	
	
	inclk = XR16L78X_INPUT_CLK / (sample * prescale);
	
	// calc divider with rounding to nearest integer
	return (inclk + (baudrate/2) - 1) / baudrate;
}

static inline XR16L78XUart * GetUartPtr( int comPort)
{
	comPort -= FIRST_EXTERN_CHANNEL;
	
	if (comPort >= 0 && comPort < g_XR16L78X_USART_Driver.channels && g_XR16L78X_USART_Driver.chip) 
	{
		return (XR16L78XUart *) &g_XR16L78X_USART_Driver.chip->ch[comPort];
	}
	return NULL;	
}


BOOL XR16L78X_USART_Driver::Initialize( int comPort, int BaudRate , int Parity, int DataBits, int StopBits, int FlowValue )
{
	XR16L78XUart *uart;
	UINT32 tdiv;
	unsigned char mode = 0;
	
	if (g_XR16L78X_USART_Driver.chip != (XR16L78XChip *) XR16L78X_BASE_ADDR) {
		g_XR16L78X_USART_Driver.chip = (XR16L78XChip *)	XR16L78X_BASE_ADDR;
		
		// get chip type
		if (g_XR16L78X_USART_Driver.chip->config.device == 0x24) 
		{
			g_XR16L78X_USART_Driver.channels = 4;
			debug_printf("XR16L784 4-channel USART detected\r\n");
		} 
		else if (g_XR16L78X_USART_Driver.chip->config.device == 0x28)
		{
			g_XR16L78X_USART_Driver.channels = 8;
			debug_printf("XR16L788 8-channel USART detected\r\n");
		} 
		else
		{
			debug_printf("XR16L78x ERROR, NO USART DETECTED\r\n");
			g_XR16L78X_USART_Driver.channels = 0;
			return FALSE;
		}
		
		// make realy sure they are cleared once
		for (int i=0;i<g_XR16L78X_USART_Driver.channels;i++) 
		{
			g_XR16L78X_USART_Driver.redirect[i].m_LineIsrCallback = NULL;
			g_XR16L78X_USART_Driver.redirect[i].m_ModemIsrCallback = NULL;
			g_XR16L78X_USART_Driver.redirect[i].m_RxIsrCallback = NULL;
			g_XR16L78X_USART_Driver.redirect[i].m_TxIsrCallback = NULL;
		}
		g_XR16L78X_USART_Driver.m_ChannelOpen = 0;
		g_XR16L78X_USART_Driver.chip->config.sample = 0;						// x16		
	}
	
	// compensate system uarts
	uart = GetUartPtr(comPort);
	if (uart == NULL) 
	{
		return FALSE;
	}

	// reset channel
	g_XR16L78X_USART_Driver.chip->config.reset  = 1 << (comPort-FIRST_EXTERN_CHANNEL);	// reset channel
	
	// get isr vector - this must be done all the time as GPIO will "forget" about it after soft reset
#ifdef XR16L78X_USART_USE_PIO_IRQ
	CPU_GPIO_EnableInputPin( XR16L78X_USART_USE_PIO_IRQ, 
							 FALSE, 
							 XR16L78X_USART_Driver::USART_GPIOISRVector, 
							 GPIO_INT_EDGE_LOW, 
							 RESISTOR_PULLUP);
#else
	CPU_INTC_ActivateInterrupt( XR16L78X_USART_INT_LINE, XR16L78X_USART_Driver::USART_ISR, (void*)(size_t)0);
#endif									
	
	// mark as open
	g_XR16L78X_USART_Driver.m_ChannelOpen |= (1 << comPort-FIRST_EXTERN_CHANNEL);

	// baudrate to tdiv. 16 times oversample and prescaler is 4 (XR16L78X_MCR_PRESCALE)
	tdiv = CalcBaudrate(BaudRate,16,4);
	//JPrint("%d: TC=%ld\n",comPort,tdiv);
	
	// extended feature enable
	uart->efr = 0x10;
	
	// set baudrate
	uart->lcr  			= XR16L78X_LCR_SETDIVISOR;
	uart->XR16L78X_DIV0 = tdiv&0xff;
	uart->XR16L78X_DIV1 = (tdiv>>8)&0xff;
	
	// convert Parity, DataBits and StopBits in lcr steup.
	switch (Parity) {
		case USART_PARITY_ODD:
			mode = XR16L78X_LCR_ODDPARITY;
			break;
		case USART_PARITY_EVEN:
			mode = XR16L78X_LCR_EVENPARITY;
			break;
		case USART_PARITY_MARK:
			mode = XR16L78X_LCR_PARITYSET;
			break;
		case USART_PARITY_SPACE:
			mode = XR16L78X_LCR_PARITYCLR;
			break;
		default:
			mode = XR16L78X_LCR_NOPARITY;
			break;
	}
	
	switch (StopBits) {
		case USART_STOP_BITS_ONEPOINTFIVE:
		case USART_STOP_BITS_TWO:
			mode |= XR16L78X_2_STOP_BITS;
			break;
		default:
			mode |= XR16L78X_1_STOP_BITS;
			break;
	}
	
	switch (DataBits) {
		case 5:
			mode |= XR16L78X_5_BITS;
			break;
		case 6:
			mode |= XR16L78X_6_BITS;
			break;
		case 7:
			mode |= XR16L78X_7_BITS;
			break;
		default:
			mode |= XR16L78X_8_BITS;
			break;
	}
	
	// init channels	
	uart->lcr  			= mode;
	uart->XR16L78X_FIFO = XR16L78X_FIFO_ENABLE | XR16L78X_FIFO_FLUSH;
	
	// UART can support HW driven half duplex (RS485)
	if (FlowValue == USART_FLOW_HALF_DUPLEX) 
	{
		// enable rs485 feature
		uart->fctr = XR16L78X_FCTR_RS485_ON | XR16L78X_FCTR_TRG_SEL;
		uart->msr  = (XR16L78X_RS485_DELAY << 4);
		// master enable 
		// comPort 5 HALF_DUPLEX requires DTR active low
		uart->mcr  = XR16L78X_MCR_PRESCALE | XR16L78X_MCR_DTR; 
	} 
	else 
	{
		uart->fctr = XR16L78X_FCTR_TRG_SEL;
		if (comPort == 6)
		{
			uart->mcr  = XR16L78X_MCR_PRESCALE | XR16L78X_MCR_RTS | XR16L78X_MCR_DTR;	
		}
		else
		{
			uart->mcr  = XR16L78X_MCR_PRESCALE | XR16L78X_MCR_RTS;	
		}
	}
	
	// setup fifo, enhanced mode, trigger levels
	uart->txfifo 		= (XR16L78X_FIFO_SIZE * 3) / 4;	// 3/4 of fifo
	uart->rxfifo 		= XR16L78X_FIFO_SIZE / 2; //(XR16L78X_FIFO_SIZE * 3) / 4;	// 3/4 of fifo

	// Rx,Tx and RxLineStatus interrupt enable
	uart->ier = 0xF;	
	
	return TRUE;
}

BOOL XR16L78X_USART_Driver::Uninitialize( int comPort )
{
	GLOBAL_LOCK(irq);
	
	XR16L78XUart *uart = GetUartPtr(comPort);

	if (uart) 
	{
		// reset int enable
		uart->ier = 0;
		// mark as closed
		g_XR16L78X_USART_Driver.m_ChannelOpen &= ~(1 << comPort-FIRST_EXTERN_CHANNEL);
		// reset channel
		g_XR16L78X_USART_Driver.chip->config.reset  = 1 << (comPort-FIRST_EXTERN_CHANNEL);
		return TRUE;
	}
	return FALSE;
}

BOOL XR16L78X_USART_Driver::TxBufferEmpty( int comPort )
{
	XR16L78XUart *uart = GetUartPtr(comPort);

	if (uart) 
	{
		return uart->lsr & XR16L78X_LSR_THREMPTY;
	} 
	
	return FALSE;
}

BOOL XR16L78X_USART_Driver::TxShiftRegisterEmpty( int comPort )
{
	XR16L78XUart *uart = GetUartPtr(comPort);
	
	if (uart) 
	{
		return uart->lsr & XR16L78X_LSR_TSREMPTY;
	} 
	
	return FALSE;
}

unsigned XR16L78X_USART_Driver::WriteBurstToTxBuffer( int comPort,  UINT8 *data, unsigned len )
{
	XR16L78XUart *uart = GetUartPtr(comPort);
	unsigned burst;
	
	GLOBAL_LOCK(irq);
	
	if (uart) 
	{
		// how many will fit into fifo?
		burst = XR16L78X_FIFO_SIZE - uart->txfifo;
		if (burst >= len) {
			// we can load the entire data into the fido
			burst = len;
			len = 0;
		} 
		else 
		{
			// reduce len by burst size
			len -= burst;
		}
		// send burst
		while (burst--)
			uart->data = *data++;
	} 	
	
	return len;
}

void XR16L78X_USART_Driver::WriteCharToTxBuffer( int comPort, UINT8 c )
{
	XR16L78XUart *uart = GetUartPtr(comPort);

	if (uart) 
	{
		uart->data = c;
	} 	
}

void XR16L78X_USART_Driver::TxBufferEmptyInterruptEnable( int comPort, BOOL Enable )
{
	XR16L78XUart *uart = GetUartPtr(comPort);

	if (uart) 
	{
		if (Enable) 
			uart->ier |= XR16L78X_IER_SENT;
		else
			uart->ier &= ~XR16L78X_IER_SENT;
	} 	
}

BOOL XR16L78X_USART_Driver::TxBufferEmptyInterruptState( int comPort )
{
	XR16L78XUart *uart = GetUartPtr(comPort);
	
	if (uart) 
	{
		return uart->isr & XR16L78X_ID_SENT;
	} 
	
	return FALSE;
}

void XR16L78X_USART_Driver::RxBufferFullInterruptEnable( int comPort, BOOL Enable )
{
	XR16L78XUart *uart = GetUartPtr(comPort);

	if (uart) 
	{
		if (Enable) 
			uart->ier |= XR16L78X_IER_RECEIVED;
		else 
			uart->ier &= ~XR16L78X_IER_RECEIVED;
	}	
}

BOOL XR16L78X_USART_Driver::RxBufferFullInterruptState( int comPort )
{
	XR16L78XUart *uart = GetUartPtr(comPort);
	
	if (uart) 
	{
		return uart->isr & XR16L78X_IER_RECEIVED;
	} 
	
	return FALSE;
}

BOOL XR16L78X_USART_Driver::TxHandshakeEnabledState( int comPort )
{
    // TODO: Add handshake code
    return TRUE;
}

void XR16L78X_USART_Driver::ProtectPins( int comPort, BOOL On )
{
}

void XR16L78X_USART_Driver::GetPins(int comPort, GPIO_PIN& rxPin, GPIO_PIN& txPin, GPIO_PIN& ctsPin, GPIO_PIN& rtsPin)
{
	rxPin = GPIO_PIN_NONE;
	txPin = GPIO_PIN_NONE;
	ctsPin = GPIO_PIN_NONE;
	rtsPin = GPIO_PIN_NONE;            

	return;
}

void  XR16L78X_USART_Driver::BaudrateBoundary(int ComPortNum, UINT32& maxBaudrateHz, UINT32& minBaudrateHz)
{
    maxBaudrateHz = 230400;//XR16L78X_USART::c_MAX_BAUDRATE;
    minBaudrateHz = 9600;//XR16L78X_USART::c_MIN_BAUDRATE;
}

BOOL XR16L78X_USART_Driver::IsBaudrateSupported(int ComPortNum, UINT32 & BaudrateHz)
{
    return true;
}

#ifdef XR16L78X_USART_USE_PIO_IRQ
void XR16L78X_USART_Driver::USART_GPIOISRVector( GPIO_PIN Pin, BOOL PinState, void* Param )
#else
void XR16L78X_USART_Driver::USART_ISR( void *x )
#endif
{
    char c;
    UINT32 irqid, fill;
	XR16L78XUart *uart;	
	int comPort;
	UINT8 lsr, msr, trigger;
	
	GLOBAL_LOCK(irq);

	// while there is something pending
	while (g_XR16L78X_USART_Driver.chip->config.isr & 0xf) {
		// handle all pending channels
		for (comPort=0;comPort<g_XR16L78X_USART_Driver.channels;comPort++) {		
			if ((1 << comPort) & g_XR16L78X_USART_Driver.chip->config.isr) {
				
				// channel pointer
				uart = &g_XR16L78X_USART_Driver.chip->ch[comPort];

				while (!((irqid = uart->isr) & XR16L78X_ID_PENDING)) {
			        switch(irqid & XR16L78X_ID_MASK) {
			          /*------------------------------------------------------------*/
			          /* RECEIVE ERROR INTERRUPT SERVICE                            */
			          /*------------------------------------------------------------*/
			          case XR16L78X_ID_LINESTATUS:
					    lsr = uart->lsr;
						if (g_XR16L78X_USART_Driver.redirect[comPort].m_LineIsrCallback) {
							g_XR16L78X_USART_Driver.redirect[comPort].m_LineIsrCallback(comPort + FIRST_EXTERN_CHANNEL,
																lsr,
																uart->data,	
																g_XR16L78X_USART_Driver.redirect[comPort].m_LineParam);
						} 						
			            break;
			          /*------------------------------------------------------------*/
			          /* RECEIVE INTERRUPT SERVICE                                  */
			          /*------------------------------------------------------------*/
			          case XR16L78X_ID_RECEIVED:   /* Nach Datenempfamg */
					    if (g_XR16L78X_USART_Driver.redirect[comPort].m_RxIsrCallback) {
							fill = uart->rxfifo;						
							while (fill) {
								g_XR16L78X_USART_Driver.redirect[comPort].m_RxIsrCallback(comPort + FIRST_EXTERN_CHANNEL,
																fill,
																&uart->data,	
																g_XR16L78X_USART_Driver.redirect[comPort].m_RxParam);
							    fill = uart->rxfifo;
							}
						} 
						else 
						{
							fill = uart->rxfifo;						
							while (fill) 
							{
								c = uart->data;
								USART_AddCharToRxBuffer( (comPort + FIRST_EXTERN_CHANNEL), c );							
								fill = uart->rxfifo;
							}
							Events_Set( SYSTEM_EVENT_FLAG_COM_IN );
						}
			            break;
			          /*-------------------------------------------------------------*/
			          /* TRANSMIT INTERRUPT SERVICE                                  */
			          /*-------------------------------------------------------------*/
			          case XR16L78X_ID_SENT:       /* Nach Datensendung */
					    fill = XR16L78X_FIFO_SIZE - uart->txfifo;							
						if (g_XR16L78X_USART_Driver.redirect[comPort].m_TxIsrCallback) {
							g_XR16L78X_USART_Driver.redirect[comPort].m_TxIsrCallback(comPort + FIRST_EXTERN_CHANNEL,
																	fill,
																	&uart->data,	
																	g_XR16L78X_USART_Driver.redirect[comPort].m_TxParam);
						} else {
							while(fill && USART_RemoveCharFromTxBuffer( (comPort + FIRST_EXTERN_CHANNEL), c ))
							{
								uart->data = c;  
								fill = XR16L78X_FIFO_SIZE - uart->txfifo;
							}
							Events_Set( SYSTEM_EVENT_FLAG_COM_OUT );
						}
						break;
			          /*----------------------------------------------------*/
			          /* HARDWARE HANDSHAKE                                 */
			          /*----------------------------------------------------*/
			          case XR16L78X_ID_MODEMSTATUS:
					    msr = uart->msr;
						if (g_XR16L78X_USART_Driver.redirect[comPort].m_ModemIsrCallback) 
						{
							trigger = msr & g_XR16L78X_USART_Driver.m_RqFlags[comPort];
							if (trigger & XR16L78X_MSR_DCTS) 
							{
								g_XR16L78X_USART_Driver.redirect[comPort].m_ModemIsrCallback(comPort + FIRST_EXTERN_CHANNEL,
										USART_OPT_CTS,
										(msr & XR16L78X_MSR_CTS) != 0,
										g_XR16L78X_USART_Driver.redirect[comPort].m_ModemParam);
							}
							if (trigger & XR16L78X_MSR_DDSR) 
							{
								g_XR16L78X_USART_Driver.redirect[comPort].m_ModemIsrCallback(comPort + FIRST_EXTERN_CHANNEL,
										USART_OPT_DSR,
										(msr & XR16L78X_MSR_DSR) != 0,
										g_XR16L78X_USART_Driver.redirect[comPort].m_ModemParam);
							}
							if (trigger & XR16L78X_MSR_DCD) 
							{
								g_XR16L78X_USART_Driver.redirect[comPort].m_ModemIsrCallback(comPort + FIRST_EXTERN_CHANNEL,
										USART_OPT_DCD,
										(msr & XR16L78X_MSR_CD) != 0,
										g_XR16L78X_USART_Driver.redirect[comPort].m_ModemParam);
							}
							if (trigger & XR16L78X_MSR_DRI) 
							{
								g_XR16L78X_USART_Driver.redirect[comPort].m_ModemIsrCallback(comPort + FIRST_EXTERN_CHANNEL,
										USART_OPT_RI,
										(msr & XR16L78X_MSR_RI) != 0,
										g_XR16L78X_USART_Driver.redirect[comPort].m_ModemParam);
							}
						}
			            break;
			        }
			    } 
			}
		}
	}
}


// similar GetUartPtr() but works with uninit-uartdriver
static XR16L78XUart *GetUartPtrUnInit(int comPort)
{
	XR16L78XChip *chip = (XR16L78XChip *) XR16L78X_BASE_ADDR;
	
	comPort -= FIRST_EXTERN_CHANNEL;
		
	if (comPort >= 0) 
	{
		return (XR16L78XUart *) &chip->ch[comPort];
	}
	return NULL;	
}
	


BOOL XR16L78X_USART_Driver::GetOption(int ComPortNum, int Feature, UINT32 *Value)
{
	XR16L78XUart *uart = GetUartPtrUnInit(ComPortNum);
	
	if (uart && Value) {
		switch (Feature) {
			case USART_OPT_RTS:
				*Value = uart->mcr & XR16L78X_MCR_RTS;		
				break;
			case USART_OPT_DTR:
				*Value = uart->mcr & XR16L78X_MCR_DTR;		
				break;
			case USART_OPT_CTS:
				*Value = uart->msr & XR16L78X_MSR_CTS;		
				break;
			case USART_OPT_DSR:
				*Value = uart->msr & XR16L78X_MSR_DSR;		
				break;
			case USART_OPT_DCD:
				*Value = uart->msr & XR16L78X_MSR_CD;				
				break;
			case USART_OPT_RI:
				*Value = uart->msr & XR16L78X_MSR_RI;		
				break;
			case USART_OPT_DUPLEX:
				if ((uart->fctr & (XR16L78X_FCTR_RS485_ON | XR16L78X_FCTR_TRG_SEL)) == (XR16L78X_FCTR_RS485_ON | XR16L78X_FCTR_TRG_SEL) && (uart->mcr & XR16L78X_MCR_DTR)) {
					*Value = USART_OPT_HALFDUPLEX;					
				} else {
					*Value = USART_OPT_FULLDUPLEX;
				}
				return true;
				
			default:
				break;	
		}
	}
	return false;
}

BOOL XR16L78X_USART_Driver::SetOption(int ComPortNum, int Feature, UINT32 Value)	
{
	XR16L78XUart *uart = GetUartPtrUnInit(ComPortNum);
	ComPortNum -= FIRST_EXTERN_CHANNEL;
	
	if (uart) {
		switch (Feature) {
			case USART_OPT_SET_MODEM_CALLBACK:
				g_XR16L78X_USART_Driver.redirect[ComPortNum].m_ModemIsrCallback = (int (*)(int,int,bool,void*)) Value;
				return true;
			
			case USART_OPT_SET_MODEM_CALLBACK_ARGUMENT:
				g_XR16L78X_USART_Driver.redirect[ComPortNum].m_ModemParam = (void *) Value;
				return true;

			case USART_OPT_SET_LINE_CALLBACK:
				g_XR16L78X_USART_Driver.redirect[ComPortNum].m_LineIsrCallback = (int (*)(int,unsigned,unsigned,void*)) Value;
				return true;

			case USART_OPT_SET_LINE_CALLBACK_ARGUMENT:
				g_XR16L78X_USART_Driver.redirect[ComPortNum].m_LineParam = (void *) Value;
				return true;

			case USART_OPT_SET_RX_CALLBACK:
				g_XR16L78X_USART_Driver.redirect[ComPortNum].m_RxIsrCallback = (int (*)(int,unsigned,volatile UINT8 *,void*)) Value;
				return true;

			case USART_OPT_SET_RX_CALLBACK_ARGUMENT:
				g_XR16L78X_USART_Driver.redirect[ComPortNum].m_RxParam = (void *) Value;
				return true;

			case USART_OPT_SET_TX_CALLBACK:
				g_XR16L78X_USART_Driver.redirect[ComPortNum].m_TxIsrCallback = (int (*)(int,unsigned,volatile UINT8 *,void*)) Value;
				return true;

			case USART_OPT_SET_TX_CALLBACK_ARGUMENT:
				g_XR16L78X_USART_Driver.redirect[ComPortNum].m_TxParam = (void *) Value;
				return true;

			case USART_OPT_ADD_TO_RQMASK:
				switch (Value) {
					case USART_OPT_DSR:
						g_XR16L78X_USART_Driver.m_RqFlags[ComPortNum] |= XR16L78X_MSR_DDSR;
						return true;
					case USART_OPT_DCD:
						g_XR16L78X_USART_Driver.m_RqFlags[ComPortNum] |= XR16L78X_MSR_DCD;
						return true;
					case USART_OPT_CTS:
						g_XR16L78X_USART_Driver.m_RqFlags[ComPortNum] |= XR16L78X_MSR_DCTS;
						return true;
					case USART_OPT_RI:
						g_XR16L78X_USART_Driver.m_RqFlags[ComPortNum] |= XR16L78X_MSR_DRI;
						return true;
					default:
						break;
				}
				break;
			
			case USART_OPT_DEL_FROM_RQMASK:
				switch (Value) {
					case USART_OPT_DSR:
						g_XR16L78X_USART_Driver.m_RqFlags[ComPortNum] &= ~XR16L78X_MSR_DDSR;
						return true;
					case USART_OPT_DCD:
						g_XR16L78X_USART_Driver.m_RqFlags[ComPortNum] &= ~XR16L78X_MSR_DCD;
						return true;
					case USART_OPT_CTS:
						g_XR16L78X_USART_Driver.m_RqFlags[ComPortNum] &= ~XR16L78X_MSR_DCTS;
						return true;
					case USART_OPT_RI:
						g_XR16L78X_USART_Driver.m_RqFlags[ComPortNum] &= ~XR16L78X_MSR_DRI;
						return true;
					default:
						break;
				}
				break;
			
			case USART_OPT_RTS:
				if (Value)
					uart->mcr |= XR16L78X_MCR_RTS;
				else 
					uart->mcr &= ~XR16L78X_MCR_RTS;
				break;
			
			case USART_OPT_DTR:
				if (Value)
					uart->mcr |= XR16L78X_MCR_DTR;
				else 
					uart->mcr &= ~XR16L78X_MCR_DTR;
				break;
			
			case USART_OPT_DUPLEX:
				if (Value == USART_OPT_HALFDUPLEX) {
					// set DTR to 1, forcing /DTR to 0
					uart->mcr |= XR16L78X_MCR_DTR;
					// drive RTS by AutoEnable
					uart->fctr = (XR16L78X_FCTR_RS485_ON | XR16L78X_FCTR_TRG_SEL);				
				} else {
					// set DTR to 0, forcing /DTR to 1
					uart->mcr &= ~XR16L78X_MCR_DTR;
					// need to set RTS to 1, forcing /RTS to 0
					uart->mcr |= XR16L78X_MCR_RTS;
					// disable AutoEnable
					uart->fctr = (XR16L78X_FCTR_TRG_SEL);					
				}
				break;
			
			default:
				break;	
		}
	}
	return false;
}
